/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package JPAControllers;

import JPAControllers.exceptions.IllegalOrphanException;
import JPAControllers.exceptions.NonexistentEntityException;
import Persistencia.Informe;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Persistencia.Sesion;
import Persistencia.Comentario;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author veinti
 */
public class InformeJpaController {

    public InformeJpaController() {
        emf = Persistence.createEntityManagerFactory("fisiosoftJDVPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Informe informe) throws IllegalOrphanException {
        if (informe.getComentarioList() == null) {
            informe.setComentarioList(new ArrayList<Comentario>());
        }
        List<String> illegalOrphanMessages = null;
        Sesion sesionOrphanCheck = informe.getSesion();
        if (sesionOrphanCheck != null) {
            Informe oldInformeOfSesion = sesionOrphanCheck.getInforme();
            if (oldInformeOfSesion != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("The Sesion " + sesionOrphanCheck + " already has an item of type Informe whose sesion column cannot be null. Please make another selection for the sesion field.");
            }
        }
        if (illegalOrphanMessages != null) {
            throw new IllegalOrphanException(illegalOrphanMessages);
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Sesion sesion = informe.getSesion();
            if (sesion != null) {
                sesion = em.getReference(sesion.getClass(), sesion.getIdSesion());
                informe.setSesion(sesion);
            }
            List<Comentario> attachedComentarioList = new ArrayList<Comentario>();
            for (Comentario comentarioListComentarioToAttach : informe.getComentarioList()) {
                comentarioListComentarioToAttach = em.getReference(comentarioListComentarioToAttach.getClass(), comentarioListComentarioToAttach.getIdComentario());
                attachedComentarioList.add(comentarioListComentarioToAttach);
            }
            informe.setComentarioList(attachedComentarioList);
            em.persist(informe);
            if (sesion != null) {
                sesion.setInforme(informe);
                sesion = em.merge(sesion);
            }
            for (Comentario comentarioListComentario : informe.getComentarioList()) {
                Informe oldInformeOfComentarioListComentario = comentarioListComentario.getInforme();
                comentarioListComentario.setInforme(informe);
                comentarioListComentario = em.merge(comentarioListComentario);
                if (oldInformeOfComentarioListComentario != null) {
                    oldInformeOfComentarioListComentario.getComentarioList().remove(comentarioListComentario);
                    oldInformeOfComentarioListComentario = em.merge(oldInformeOfComentarioListComentario);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Informe informe) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Informe persistentInforme = em.find(Informe.class, informe.getIdInforme());
            Sesion sesionOld = persistentInforme.getSesion();
            Sesion sesionNew = informe.getSesion();
            List<Comentario> comentarioListOld = persistentInforme.getComentarioList();
            List<Comentario> comentarioListNew = informe.getComentarioList();
            List<String> illegalOrphanMessages = null;
            if (sesionNew != null && !sesionNew.equals(sesionOld)) {
                Informe oldInformeOfSesion = sesionNew.getInforme();
                if (oldInformeOfSesion != null) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("The Sesion " + sesionNew + " already has an item of type Informe whose sesion column cannot be null. Please make another selection for the sesion field.");
                }
            }
            for (Comentario comentarioListOldComentario : comentarioListOld) {
                if (!comentarioListNew.contains(comentarioListOldComentario)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Comentario " + comentarioListOldComentario + " since its informe field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (sesionNew != null) {
                sesionNew = em.getReference(sesionNew.getClass(), sesionNew.getIdSesion());
                informe.setSesion(sesionNew);
            }
            List<Comentario> attachedComentarioListNew = new ArrayList<Comentario>();
            for (Comentario comentarioListNewComentarioToAttach : comentarioListNew) {
                comentarioListNewComentarioToAttach = em.getReference(comentarioListNewComentarioToAttach.getClass(), comentarioListNewComentarioToAttach.getIdComentario());
                attachedComentarioListNew.add(comentarioListNewComentarioToAttach);
            }
            comentarioListNew = attachedComentarioListNew;
            informe.setComentarioList(comentarioListNew);
            informe = em.merge(informe);
            if (sesionOld != null && !sesionOld.equals(sesionNew)) {
                sesionOld.setInforme(null);
                sesionOld = em.merge(sesionOld);
            }
            if (sesionNew != null && !sesionNew.equals(sesionOld)) {
                sesionNew.setInforme(informe);
                sesionNew = em.merge(sesionNew);
            }
            for (Comentario comentarioListNewComentario : comentarioListNew) {
                if (!comentarioListOld.contains(comentarioListNewComentario)) {
                    Informe oldInformeOfComentarioListNewComentario = comentarioListNewComentario.getInforme();
                    comentarioListNewComentario.setInforme(informe);
                    comentarioListNewComentario = em.merge(comentarioListNewComentario);
                    if (oldInformeOfComentarioListNewComentario != null && !oldInformeOfComentarioListNewComentario.equals(informe)) {
                        oldInformeOfComentarioListNewComentario.getComentarioList().remove(comentarioListNewComentario);
                        oldInformeOfComentarioListNewComentario = em.merge(oldInformeOfComentarioListNewComentario);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = informe.getIdInforme();
                if (findInforme(id) == null) {
                    throw new NonexistentEntityException("The informe with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Informe informe;
            try {
                informe = em.getReference(Informe.class, id);
                informe.getIdInforme();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The informe with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Comentario> comentarioListOrphanCheck = informe.getComentarioList();
            for (Comentario comentarioListOrphanCheckComentario : comentarioListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Informe (" + informe + ") cannot be destroyed since the Comentario " + comentarioListOrphanCheckComentario + " in its comentarioList field has a non-nullable informe field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Sesion sesion = informe.getSesion();
            if (sesion != null) {
                sesion.setInforme(null);
                sesion = em.merge(sesion);
            }
            em.remove(informe);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Informe> findInformeEntities() {
        return findInformeEntities(true, -1, -1);
    }

    public List<Informe> findInformeEntities(int maxResults, int firstResult) {
        return findInformeEntities(false, maxResults, firstResult);
    }

    private List<Informe> findInformeEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Informe.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Informe findInforme(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Informe.class, id);
        } finally {
            em.close();
        }
    }

    public int getInformeCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Informe> rt = cq.from(Informe.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
